/**
 * 
 */
package com.ubo.java.model.classifier;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import com.ubo.java.model.EVisibility;
import com.ubo.java.model.PackageModel;
import com.ubo.java.model.comment.Comment;
import com.ubo.java.model.methode.Prototype;

/**
 * @author saludegu
 * 
 */
public abstract class AClassifier implements IClassifier {

	/**
	 * Liste des interfaces implémentées ou étendues par le classifier.
	 */
	protected Set<Interface> mInterfaceImplemented;

	/**
	 * Nom du classifier.
	 */
	protected final String mClassifierName;

	/**
	 * Package d'appartenance du classifier.
	 */
	protected final PackageModel mPackage;

	/**
	 * Visibilité du classifier.
	 */
	protected final EVisibility mVisibility;

	/**
	 * Commentaire du classifier.
	 */
	protected Comment mComment;

	/**
	 * 
	 * Constructor
	 * 
	 * @param classifierName
	 */
	public AClassifier(String classifierName, PackageModel packageClass,
			EVisibility visibility) {
		mClassifierName = classifierName;
		mPackage = packageClass;
		mVisibility = visibility;
	}

	/**
	 * Indique si la classe doit être générée ou non .
	 * 
	 * @return
	 */
	public boolean generationNeeded() {
		return true;
	}

	/**
	 * Ajout d'une collection d'interfaces implémentés à la classe.
	 * 
	 * @param interfaces
	 */
	public void implementsInterfaces(Collection<Interface> interfaces) {
		if (mInterfaceImplemented == null)
			mInterfaceImplemented = new HashSet<Interface>(0);
		mInterfaceImplemented.addAll(interfaces);
	}
	
	/**
	 * Ajout d'une collection d'interfaces implémentés à la classe.
	 * 
	 * @param interfaces
	 */
	public void implementsInterfaces(Interface interfaces) {
		if (mInterfaceImplemented == null)
			mInterfaceImplemented = new HashSet<Interface>(0);
		mInterfaceImplemented.add(interfaces);
	}


	/**
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((mClassifierName == null) ? 0 : mClassifierName.hashCode());
		result = prime * result
				+ ((mPackage == null) ? 0 : mPackage.hashCode());
		return result;
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		AClassifier other = (AClassifier) obj;
		if (mClassifierName == null) {
			if (other.mClassifierName != null)
				return false;
		} else if (!mClassifierName.equals(other.mClassifierName))
			return false;
		if (mPackage == null) {
			if (other.mPackage != null)
				return false;
		} else if (!mPackage.equals(other.mPackage))
			return false;
		return true;
	}

	/**
	 * @return the mInterfaceImplemented
	 */
	public Set<Interface> getInterfaceImplemented() {
		return mInterfaceImplemented;
	}

	/**
	 * @return the mClassifierName
	 */
	@Override
	public String getClassifierName() {
		return mClassifierName;
	}

	/**
	 * @return the mPackage
	 */
	public PackageModel getPackage() {
		return mPackage;
	}

	/**
	 * Affiche le chemin d'une classe.
	 * 
	 * @return
	 */
	public String printPath() {
		return mPackage.printPath() + "." + mClassifierName;
	}

	/**
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return printPath();
	}

	/**
	 * 
	 * @return mVisibility.
	 */
	public EVisibility getVisibility() {
		return mVisibility;
	}

	/**
	 * Getter du commentaire du classifier.
	 * 
	 * @return
	 */
	public Comment getComment() {
		return mComment;
	}
	
	abstract Collection<Prototype> getPrototypes();
	
}
